package com.example.shell.util;

import com.example.shell.model.entity.AttendanceRecord;
import com.example.shell.model.entity.UserInfo;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class ParseDomXPath {

    private static final Map<String, String> nsMap = new HashMap<>();

    static {
        nsMap.put("s", "http://schemas.xmlsoap.org/soap/envelope/");
        nsMap.put("ns", "EnLong.Lib.WCF");
        nsMap.put("a", "http://schemas.datacontract.org/2004/07/EnLong.Lib.WCF");
        nsMap.put("b", "http://schemas.microsoft.com/2003/10/Serialization/Arrays");
        nsMap.put("c", "http://schemas.datacontract.org/2004/07/EnLong.BPSupports.SysStandardDefine");
        nsMap.put("d", "http://schemas.datacontract.org/2004/07/EnLong.Lib.Data.SLDatatable");
    }

    public static UserInfo parseLoginResult(String xml) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // 必须开启命名空间支持
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));

        XPathFactory xPathfactory = XPathFactory.newInstance();
        XPath xpath = xPathfactory.newXPath();

        // 设置命名空间上下文
        xpath.setNamespaceContext(new NamespaceContextMap(nsMap));

        // XPath 路径
        String basePath = "/s:Envelope/s:Body/ns:InvokeResponse/ns:InvokeResult/a:Parameters/b:anyType";

        UserInfo userInfo = new UserInfo();
        userInfo.setIndependentName(xpath.evaluate(basePath + "/c:IndependentName", doc));
        userInfo.setJobName(xpath.evaluate(basePath + "/c:JobName", doc));
        userInfo.setLoginID(xpath.evaluate(basePath + "/c:LoginID", doc));
        userInfo.setLoginIdentity(xpath.evaluate(basePath + "/c:LoginIdentity", doc));
        userInfo.setOrgName(xpath.evaluate(basePath + "/c:OrgName", doc));
        userInfo.setUserCode(xpath.evaluate(basePath + "/c:UserCode", doc));
        userInfo.setUserName(xpath.evaluate(basePath + "/c:UserName", doc));
        return userInfo;
    }

    public static List<AttendanceRecord> parseCheckinListResult(String xml) throws Exception {
        List<AttendanceRecord> list = new ArrayList<>();

        // DOM 解析器初始化
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // 支持命名空间
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xml)));

        // XPath 初始化
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();

        // 设置命名空间上下文
        xpath.setNamespaceContext(new NamespaceContextMap(nsMap));

        // 获取所有 Row 节点
        NodeList rowNodes = (NodeList) xpath.evaluate(
                "//d:Rows/d:ArrayOfDTOTableCell",
                doc,
                XPathConstants.NODESET
        );


        // 解析每一行
        for (int i = 0; i < rowNodes.getLength(); i++) {
            Node rowNode = rowNodes.item(i);

            NodeList cellNodes = (NodeList) xpath.evaluate(
                    "d:DTOTableCell",
                    rowNode,
                    XPathConstants.NODESET
            );

            AttendanceRecord record = new AttendanceRecord();

            for (int j = 0; j < cellNodes.getLength(); j++) {
                Element cell = (Element) cellNodes.item(j);
                String fieldName = xpath.evaluate("d:FieldName", cell);
                String value = xpath.evaluate("d:Value", cell);

                // 通过反射设置值
                try {
                    // 根据 fieldName 构建 setter 方法名
                    String setterMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                    Method setterMethod = AttendanceRecord.class.getMethod(setterMethodName, String.class);
                    // 通过反射调用 setter 方法
                    setterMethod.invoke(record, value);
                } catch (Exception e) {
                    // 处理异常，例如字段没有对应的 setter 或类型不匹配
                }
            }

            record.fill();
            list.add(record);
        }
        return list;
    }

    // 自定义命名空间上下文处理器
    static class NamespaceContextMap implements NamespaceContext {
        private final Map<String, String> prefixMap;

        public NamespaceContextMap(Map<String, String> prefixMap) {
            this.prefixMap = prefixMap;
        }

        @Override
        public String getNamespaceURI(String prefix) {
            return prefixMap.getOrDefault(prefix, XMLConstants.NULL_NS_URI);
        }

        @Override
        public String getPrefix(String namespaceURI) {
            for (Map.Entry<String, String> entry : prefixMap.entrySet()) {
                if (entry.getValue().equals(namespaceURI)) {
                    return entry.getKey();
                }
            }
            return null;
        }

        @Override
        public Iterator getPrefixes(String namespaceURI) {
            return prefixMap.keySet().iterator();
        }
    }
}
